#pragma once
#include <vector>
#include "Eigen/Dense"
#include <iostream>
#include "electric_bases.h"
using namespace Eigen;
using namespace std;

#define V_nodeC V_IGBT[0]
#define V_node1 V_IGBT[1]
#define V_nodeD V_IGBT[2]
#define V_nodeG V_IGBT[3]
#define V_nodeS V_IGBT[4]
#define V_nodeAUX V_IGBT[5]
#define V_nodemidFWD V_IGBT[6]
#define V_nodeE V_IGBT[7]

class IGBT_device_level : public electric_base
{
public:
    bool sig = 0;
    void setSig(bool sig)
    {
        this->sig = sig;
        Vs = (sig == false ? (-20) : 20);
    }
    bool simple = false;

    double G[8][8] = {0};
    double f[8] = {0};
    Matrix<double, 8, 8> G8;
    Matrix<double, 8, 1> J8;
    Matrix<double, 1, 1> Y11;
    Matrix<double, 1, 6> Y12;
    Matrix<double, 6, 1> Y21;
    Matrix<double, 6, 6> Y22;
    Matrix<double, 6, 6> Y22_inv;
    Matrix<double, 1, 1> Jex;
    Matrix<double, 6, 1> Jin;
    Matrix<double, 1, 1> Vex;
    Matrix<double, 6, 1> Vin;
    Matrix<double, 1, 1> Geq; // 触发信号内置了，IGBT实际上就是一个单端口电路
    Matrix<double, 1, 1> Jeq;
    double Gout, Jout;
    double simulation_time;
    double V_IGBT[8] = {0};
    double V_IGBT_last[8] = {0};
    // V_nodeC, V_node1, V_nodeD, V_nodeG, V_nodeS, V_nodeAUX, V_nodemidFWD, V_nodeE
    double h /*attention: connect to delt in begin()!*/, Vs, VGS_old, QCE_old, QCG_old, Qeb_old = 0,
        Itotal, VGS, QCE, QCG, Qeb; // input and output parameters

    double VP, K, KLM, A_FET, M_FET, N_FET, BN, M_BJT, ISAT_BJT, Vsat, Isat, VDS, ID;
    double GmosVGS, GmosVDS, Imoseq, ID_Factor1, ID_Factor2, ID_Factor3, d1VDS, d2VDS, d3VDS, d2VGS, d3VGS;
    double k, q, T, VT, VEB, IB, Gbjt, IBeq, RP_BJT, M_FWD, ISAT_FWD, IFWD, GFWD, IFWDeq, VFVD;
    double C_GE, GCGS, ICGS_eq, Rg;
    // FWD
    double RB_FWD;
    double INOM;
    // C_CE
    double C0_CE;
    double VDIFF_CE;
    double VSHIFT_CE;
    double ALPHA_CE;
    double BETA_CE;
    double DELTA_CE;
    double VCE, B, VVJNCT_CE, CEa, CEb, AA_CE, BB_CE;
    double CCE, ICE, GCE, ICEeq;
    // C_CG
    double C0_CG;
    double VDIFF_CG_OFF;
    double VDIFF_CG_ON;
    double VSHIFT_CG_OFF;
    double VSHIFT_CG_ON;
    double ALPHA_CG_OFF;
    double ALPHA_CG_ON;
    double BETA_CG_OFF;
    double BETA_CG_ON;
    double DELTA_CG_OFF;
    double DELTA_CG_ON;
    double VCG, VVJNCT_CG, CGa, CGb, AA_CG, BB_CG, CCG, ICG, GCG, ICGeq;
    // Ceb(diff)
    double TAU_BE;
    double Ceb, Ieb, GCeb, ICebeq;
    // connector
    double LG;
    double LC;
    double RC;
    double LE;
    double RE;
    double RAUX;
    double LAUX;
    // internal parameters

    void begin();
    void solve();
    void dsdyn_in_iteration(double delt, double simulation_time);
    void dsdyn_out_iteration(double delt, double simulation_time){};
    void dsout_in_iteration();
    void dsout_out_iteration();
    void update();

    double max(vector<double> &data);
};
